﻿using CaltechSoft.Service.DBCommand;
using CaltechSoft.Service.EntityFW.Context;
using CaltechSoft.Service.EntityFW.Entity;
using CaltechSoft.Service.EntityFW.Repository;
using CaltechSoft.Service.Infrastructure.Utility;
using CaltechSoft.Service.Repositories;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace CaltechSoft.Service.CommandService
{
    public class CustomerCommandService : BaseRepository<Customer>, ICustomerCommandService
    {
        public CaltechContext Context
        {
            get
            {
                return new CaltechContext();
            }
        }

        private readonly IUnitOfWork _unitOfWork;
        public CustomerCommandService(IUnitOfWork unitOfWork)
        {
            _unitOfWork = unitOfWork;

        }

        public int CreateCustomer(CreateCustomerCommand command)
        {
            Guard.ArgumentIsNotNull(command, "command");
            Guard.Against<ArgumentException>(string.IsNullOrEmpty(command.CustomerName), "Customer name can not be empty");

            using (var context = Context)
            {
                var existingItem = context.Set<Customer>().FirstOrDefault(n => n.Name == command.CustomerName);
                if (existingItem != null)
                {
                    return existingItem.Id;
                }
                Customer customer = new Customer { Name = command.CustomerName, Address = command.Address, ContactPersonName = command.ContactPerson };
                context.Set<Customer>().Add(customer);
                context.SaveChanges();
                return customer.Id;
            }
        }

        public int AddCustomer(Customer command)
        {
            Guard.ArgumentIsNotNull(command, "command");
            Guard.Against<ArgumentException>(string.IsNullOrEmpty(command.Name), "Customer name can not be empty");

            using (var context = Context)
            {
                var existingItem = context.Set<Customer>().FirstOrDefault(n => n.Name == command.Name);
                Guard.Against<ArgumentException>(existingItem != null, "This customer name have been already existed !");
                context.Set<Customer>().Add(command);
                context.SaveChanges();
                return command.Id;
            }
        }

        public int UpdateCustomer(Customer command)
        {
            Guard.ArgumentIsNotNull(command, "command");
            Guard.Against<ArgumentException>(string.IsNullOrEmpty(command.Name), "Customer name can not be empty");

            var existingItem = _unitOfWork.Repository<Customer>().Get(n => n.Name == command.Name && n.Id != command.Id).Any();
            Guard.Against<ArgumentException>(existingItem, "This customer name have been already existed !");

            _unitOfWork.Repository<Customer>().Update(command);
            _unitOfWork.Save();
            return command.Id;
        }

        public void DeleteCustomer(int customerId)
        {
            Guard.Against<ArgumentException>(customerId < 0, "CustomerId is invalid");

            var existingItem = _unitOfWork.Repository<CustomerEquipment>().Get(n => n.CustomerId == customerId).Any();
            Guard.Against<ArgumentException>(existingItem, "This customer references many equipments. Can not delete this customer!");

            _unitOfWork.Repository<Customer>().Delete(customerId);
            _unitOfWork.Save();
        }


        public IQueryable<Customer> Get()
        {
            return Context.Customers;
        }
    }
}
